
import com.bm.util.ConfigReader;
import com.bm.util.MrArrayConverter;
import com.bm.util.PropertiesHandler;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.logging.Level;
import java.util.logging.Logger;

/*
 * To change this template, choose Tools | Templates and open the template in
 * the editor.
 */
/**
 *
 * @author Mirza at Bimasakti
 */
class MrServerSocket implements Runnable {

    private Socket providerSocket;
    private ObjectOutputStream out;
    private ObjectInputStream in;
    private MrArrayConverter message;
    private String id_modul ;
    private PropertiesHandler properties = null;

    public MrServerSocket(Socket server) {
        this.providerSocket = server;   
        try {
            this.properties = new PropertiesHandler();
            this.id_modul = properties.getIdModul();
        } catch (IOException ex) {
            Logger.getLogger(MrServerSocket.class.getName()).log(Level.SEVERE, null, ex);
        }        
    }

    @Override
    public void run() {
        try {
            in = new ObjectInputStream(providerSocket.getInputStream());
            out = new ObjectOutputStream(providerSocket.getOutputStream());
            //out.flush();
            
            message = (MrArrayConverter) in.readObject();
            System.out.println("Receive Act : "+message.getMethodName());
            Object[] data = message.getData();
            if (message.getMethodName().equals("MISMS.initServer")) {
                sendMessage(MI_SMS.initServer((String) data[0]));
            } else if (message.getMethodName().equals("MISMS.echoTest")) {
                sendMessage(MI_SMS.echoTest());
            } else if (message.getMethodName().equals("MISMS.getDateCreatedFile")) {
                sendMessage(MI_SMS.getDateCreatedFile((String) data[0]));
            } else if (message.getMethodName().equals("MISMS.updateMessageOutbox")) {
                try {
                    MI_SMS.updateMessageOutbox((Integer) data[0], (String) data[1], this.id_modul);
                    sendMessage("Message outbox berhasil diupdate");
                } catch (SQLException ex) {
                    sendMessage("Gagal update outbox");
                    Logger.getLogger(MrServerSocket.class.getName()).log(Level.SEVERE, null, ex);
                }
            } else if (message.getMethodName().equals("MISMS.selectFromMessageOutbox")) {
                sendMessage(MI_SMS.selectFromMessageOutbox((String) data[0], this.id_modul));
            } else if (message.getMethodName().equals("MISMS.insertIntoInbox")) {
                try {
                    boolean status = MI_SMS.insertIntoInbox((Integer) data[0], (String) data[1], (String) data[2], (String) data[3], (String) data[4], (String) data[5], (Integer) data[6], (String) data[7]);
                    sendMessage(status);
                } catch (SQLException ex) {
                    Logger.getLogger(MrServerSocket.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        } catch (ClassNotFoundException ex) {
            Logger.getLogger(SocketServer.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ioException) {
            System.out.println(ioException.getMessage());
            try {
                //Logger.getLogger(SocketServer.class.getName()).log(Level.SEVERE, null, ioException);
                DataOutputStream ds = new DataOutputStream(new BufferedOutputStream(providerSocket.getOutputStream()));
                ds.writeUTF("Tidak dapat diakses lewat browser");
                ds.close();
            } catch (IOException ex) {
                //Logger.getLogger(MrServerSocket.class.getName()).log(Level.SEVERE, null, ex);
            }            
        } finally {
            try {
                if (out != null) {                    
                    out.close();
                }
                if (in != null) {
                    in.close();
                } 
                if (!providerSocket.isClosed()){
                    
                }
            } catch (IOException ioException) {
                System.out.println(ioException.getMessage());
            }
        }
    }

    private void sendMessage(Object msg) {
        try {
            out.writeObject(msg);
            out.flush();
            System.out.println("server send: " + msg.toString());
        } catch (IOException ioException) {
            System.out.println(ioException.getMessage());
        }
    }
}

public class SocketServer {

    private static int maxConnections = 0;
    private static Thread terminateApp = null;
    public static int port = 0;

    private static String readCommnad(String command) {
        System.out.print(command);
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String inputan = null;
        try {
            inputan = br.readLine();
            return inputan;
        } catch (IOException ioe) {
            System.out.println("Anda memasukkan PORT yang salah");
            System.exit(1);
            return "";
        }
    }

    public static void main(String[] args) {
        System.out.println("Beta Version - SMS Socket Server. Last update by Mirza");
        terminateApp = new Thread(new Runnable() {
            @Override
            public void run() {
                while(true){
                    checkTerminateApp();
                    try {
                        Thread.sleep(120000);
                    } catch (InterruptedException ex) {
                        Logger.getLogger(SocketServer.class.getName()).log(Level.SEVERE, null, ex);
                    }
                }
            }
        });
        terminateApp.start();
        int i = 0;        
        try {
            port = Integer.valueOf(args[0]);
        } catch (Exception e) {
            port = 5801;
        }        
        ConfigReader.port = String.valueOf(port);        
        MI_SMS.initServer("54:04:a6:da:25:61");   
        try {
            ServerSocket listener = new ServerSocket(port);
            System.out.println("Socket server created on port "+port);
            while ((i++ < maxConnections) || (maxConnections == 0)) {
                Socket server = listener.accept();
                MrServerSocket conn = new MrServerSocket(server);
                Thread t = new Thread(conn);
                t.start();
            }
        } catch (IOException ioe) {
            System.out.println("IOException on socket listen: " + ioe);
            ioe.printStackTrace();
        }
    }
    
    public static void checkTerminateApp(){
        Calendar c = Calendar.getInstance();
        SimpleDateFormat sd = new SimpleDateFormat("HH");
        int hour = Integer.valueOf(sd.format(c.getTime()));
        sd = new SimpleDateFormat("mm");
        int minute = Integer.valueOf(sd.format(c.getTime()));
        if (hour == 23 && minute >= 55){
            System.exit(1);        
        } else {
            System.out.println("Application terminated on 23:55. Current Time: "+hour+":"+minute);
        }               
    }
}
